/**
 * AmpArchCategory.java
 * 
 * FreeZzaph is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * FreeZzaph is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.
 */

package freezzaph.plugins;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import freezzaph.exceptions.PluginException;
import freezzaph.exceptions.URLFetchException;
import freezzaph.plugins.AmpArchPlugin.AmpArchSettings;
import freezzaph.plugins.util.URLFetcher;

/**
 * Category class that takes care of what is common
 * for the Ampland Archive Categories.
 * 
 * @author FreeZzaph
 */
abstract class AmpArchCategory extends Category {
	
	abstract Pattern link();
	
	private String categoryName;
	
	private AmpArchSettings settings;

	/**
	 * Construct an Ampland Archive category
	 * 
	 * @param name the name of the category
	 * @param description the description of the category
	 * @param filter the filter of the category
	 * @param settings the plugin's download settings
	 * @param categoryURL the URL of this category
	 */
	public AmpArchCategory(String name, String description, String filter, String categoryName, AmpArchSettings settings) {
		super(name, description, filter);
		this.categoryName = categoryName;
		this.settings = settings;
	}

	/* (non-Javadoc)
	 * @see freezzaph.plugins.Category#fetch(int, int)
	 */
	@Override final public URL[] fetch(int start, int count) {
		int currentCount = 0;
		int realCount = count;
		int realStart = start;
		if (realCount == -1) realCount = 100;
		
		if (settings.getYear() == null || settings.getYear().isEmpty()) {
			throw new PluginException("Year not set. Type 'help' for more information");
		}
		
		if (settings.getMonth() == null || settings.getMonth().isEmpty()) {
			throw new PluginException("Month not set. Type 'help' for more information");
		}
		
		URL categoryUrl;
		try {
			categoryUrl = new URL("http://www.amplandarchive.com/" + settings.getYear() + "/" + settings.getMonth() + "-" + categoryName + ".html");
		} catch (MalformedURLException e) {
			throw new PluginException("Could not generate URL for download. Make sure you set 'year' and 'month' to something valid.");
		}
		
		ArrayList<URL> urls = new ArrayList<URL>();
		HashMap<String, Object> duplicatePreventor = new HashMap<String, Object>(realCount);
		
		// Fetch (X)HTML data for parsing
		String sb;
		try {
			sb = URLFetcher.fetch(categoryUrl);
		} catch (URLFetchException e) {
			throw new PluginException("Could not download category list. AmplandArchive.com may not be accessible, or the plugin may need to be updated.", e);
		}
		
		Matcher m = link().matcher(sb);
		while (realStart > 0) {
			// If not starting at 0, fast forward
			// the matcher to the appropriate starting point
			m.find();
			realStart--;
		}
		while (m.find() && currentCount < realCount) {
			String path = m.group(1);
			if (!duplicatePreventor.containsKey(path) && path.startsWith("http")) {
				// Ignore duplicates
				try {
					URL url = new URL(path);
					urls.add(url);
					currentCount++;
					duplicatePreventor.put(path, null);
				} catch (MalformedURLException e) {
					// When a URL is malformed
					// Just ignore it.
				}
			}
		}
		return urls.toArray(new URL[0]);
	}

}
